package nl.xvr.server.control;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.Semaphore;

import nl.xvr.server.core.Main;

public class RequestHandler extends Thread {
    private Semaphore semaphore;
    private Properties properties;
    private Socket socket;

    public RequestHandler(Properties properties, Socket socket, Semaphore semaphore) {
        this.properties = properties;
        this.socket = socket;
        this.semaphore = semaphore;
    }

    public void run() {
        handle();
    }

    private void handle() {		
        try
        {			
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());

            // Lees het http-request
            String line = in.readLine();
            String request = line;

            if(request.startsWith("POST")) {
                // Lees de rest van het request en haal de content length hier uit
                int contentLength = 0;
                while((line = in.readLine()).length() > 0) {
                    String parts[] = line.split(":");
                    if(parts[0].toUpperCase().equals("CONTENT-LENGTH"))
                        contentLength = Integer.parseInt(parts[1].trim());
                }

                // Lees request content (post)
                String content = "";
                if(contentLength != 0)
                {
                    char rawcontent[] = new char[contentLength];
                    in.read(rawcontent, 0, contentLength);
                    content = new String(rawcontent);
                }
                properties = saveProperties(content);
            } 

            showWebPage(out, properties);
        }
        catch(Exception e) {
            System.out.println(e);
        } finally {
            try {
                socket.close();
            }
            catch (IOException e) {
                System.out.println("Cannot close the socket.");
            }		    
        }
    }

    private Properties saveProperties(String content) {
        Properties properties = null;
        OutputStream os = null;
        try {
            boolean dir_browsing = false;
            properties = new Properties();

            String[] props = content.split("&");
            for(String prop : props) {
                String[] pTemp = prop.split("=");
                if(pTemp[0].equals("dir_browsing")) {
                    dir_browsing=true;
                } else {
                    properties.put(pTemp[0], URLDecoder.decode(pTemp[1], "UTF-8"));
                }
            }
            if(dir_browsing) {
                properties.put("dir_browsing", "checked");
            } else {
                properties.put("dir_browsing", "");
            }
            
            os = new FileOutputStream(new File(Main.CONFIGPATH));
            properties.store(os, "");
        } catch(FileNotFoundException e) {
            System.out.println("Storing properties: " + e);
        } catch(IOException e) {
            System.out.println("Storing properies: " + e);
        } finally {
            if(os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    //
                }
            }
        }

        semaphore.release();
        return properties;
    }

    private void showWebPage(DataOutputStream out, Properties properties) throws IOException {
        try { 
            out.writeBytes("HTTP/1.0 200 OK\r\n" +
                    "Content-Type: text/html\r\n" +
                    "Date: " + new Date() + "\r\n" +
            "Server: FileServer 1.0\r\n\r\n");
            out.writeBytes("<html>" +
                    "<head><title>Control Server - Settings</title></head>\r\n" +
                    "</body>\r\n" +
                    "<h1>Server Settings</h1>\r\n" +
                    "<form action=\"\" method=\"post\">\r\n" +
                    "<table>\r\n" +
                    "<tr>\r\n" +
                    "<td>Webroot: </td><td><input type=\"text\" name=\"webroot\" size=\"50\" value=\""+ properties.getProperty("webroot") + "\"/></td>\r\n" +
                    "</tr>\r\n" +
                    "<tr>\r\n" +
                    "<td>Default name for a webpage: </td><td><input type=\"text\" name=\"defaultpage\" value=\""+ properties.getProperty("defaultpage") + "\"/></td>\r\n" +
                    "</tr>\r\n" +
                    "<tr>\r\n" +
                    "<td>WebServer Port: </td><td><input type=\"text\" name=\"web_port\" size=\"3\" maxlength=\"4\" value=\""+ properties.getProperty("web_port") + "\"/></td>\r\n" +
                    "</tr>\r\n" +
                    "<tr>\r\n" +
                    "<td>ControlServer Port: </td><td><input type=\"text\" name=\"control_port\" size=\"3\" maxlength=\"4\" value=\""+ properties.getProperty("control_port") + "\"/></td>\r\n" +
                    "</tr>\r\n" +
                    "<tr>\r\n" +
                    "<td>Directory browsing: </td><td><input type=\"checkbox\" name=\"dir_browsing\"" + properties.getProperty("dir_browsing") + "/></td>\r\n" +
                    "</tr>\r\n" +
                    "<tr>\r\n" +
                    "<td colspan=\"2\"><input type=\"submit\" value=\"Opslaan!\" /></td>\r\n" +
                    "</tr>\r\n" +
                    "</table>\r\n" +
                    "</form>\r\n" +
                    "</body>\r\n" +
            "</html>"); 
        } catch (FileNotFoundException e) { 
            // file not found
            errorReport(out, socket, "404", "Not Found",
            "The requested URL was not found on this server.");
        } 
    }

    private void errorReport(DataOutputStream out, Socket connection,
            String code, String title, String msg) throws IOException
            {
        out.writeBytes("HTTP/1.0 " + code + " " + title + "\r\n" +
                "\r\n" +
                "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n" +
                "<HTML><HEAD>\r\n" +
                "<TITLE>" + code + " " + title + "</TITLE>\r\n" +
                "</HEAD><BODY>\r\n" +
                "<H1>" + title + "</H1>\r\n" + msg + "<P>\r\n" +
                "<HR><ADDRESS>FileServer 1.0 at " + 
                connection.getLocalAddress().getHostName() + 
                " Port " + connection.getLocalPort() + "</ADDRESS>\r\n" +
        "</BODY></HTML>\r\n");
            }
}
